﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Media;
using System.IO;

namespace DungDungShit
{
    class GameScreen : Screen
    {
        float pauseAlpha;

        public const int statusBarWidth = 240, mapViewWidth = 64 * 15 - statusBarWidth, mapViewHeight = 64 * 9;
        private Viewport defaultViewport, mapViewport, statusBarViewport;

        private MapContainer mapContainer;
        private Vector2 mapViewOrigin, mapViewBias = new Vector2(0, 0);

        private InputState inputState;

        private int slotNumber;
        private int frameCount;
        private DateTime time;
        private TimeSpan timeLeft;
        private bool cleared;
        private bool started = false;
        private bool played = false;

        public GameScreen(int slotNumber)
        {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);
            this.slotNumber = slotNumber;

            time = DateTime.Today;

        }
        SoundEffectInstance inst;
        public override void LoadContent()
        {
            /// 나중에 맵 형식이 정해지면 하도록
            mapContainer = new MapContainer(ScreenManager, ScreenType.Game, slotNumber);

            defaultViewport = ScreenManager.GraphicsDevice.Viewport;

            mapViewport = defaultViewport;
            mapViewport.Width = mapViewWidth;
            mapViewport.Height = mapViewHeight;

            statusBarViewport = defaultViewport;
            statusBarViewport.Width = statusBarWidth;
            statusBarViewport.Height = mapViewHeight;
            statusBarViewport.X = mapViewWidth;

                inst = ScreenManager.BGM.CreateInstance();
                inst.IsLooped = true;

                inst.Play();
            
        }

        public override void HandleInput(InputState input)
        {
            if (input.IsPauseGame())
            {
                ScreenManager.AddScreen(new PauseMenuScreen(0, mapContainer));
                mapContainer.isPaused = true;
            }
            else if (input.IsNewKeyPress(Microsoft.Xna.Framework.Input.Keys.Z))
            {
                if (mapContainer.isEscapeTile())
                {
                    mapContainer.isPaused = true;
                    MessageBoxScreen askEscapeMessageBoxScreen = new MessageBoxScreen("Would you like to escape?", true);
                    askEscapeMessageBoxScreen.Accepted += escapeMessageBox_Accepted;
                    askEscapeMessageBoxScreen.Cancelled += escapeMessageBox_Cancelled;
                    ScreenManager.AddScreen(askEscapeMessageBoxScreen);
                }
            }
            inputState = input;
        }
        int rumble = 30;
        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                      bool coveredByOtherScreen)
        {
            // Gradually fade in or out depending on whether we are covered by the pause screen.
            if (coveredByOtherScreen)
                pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1);
            else
                pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0);

            mapContainer.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen, inputState);
            if (frameCount < int.MaxValue)
                frameCount++;


            if (!mapContainer.isPaused)
            {
                if (inst.State == SoundState.Stopped)
                    inst.Play();

                time = time.AddMilliseconds(1.0 / 30.0 * 1000);
                timeLeft = mapContainer.PlayerTime - time;

                if (timeLeft.Minutes == 0)
                {
                    if (rumble > 0)
                    {
                        rumble--;
                        mapContainer.Rumble(rumble);
                    }
                    else mapContainer.notRumble();
                }
                else
                {
                    rumble = 30;
                }
                if (!started)
                {
                    mapContainer.isPaused = true;
                    started = true;
                    MessageBoxScreen readyMessageBoxScreen = new MessageBoxScreen("ARE YOU READY?\nThen Press ENTER", false);
                    readyMessageBoxScreen.Accepted += readyMessageBox_Accepted;
                    ScreenManager.AddScreen(readyMessageBoxScreen);
                }
                else if (timeLeft.Minutes == 0 && timeLeft.Seconds == 0 && timeLeft.Milliseconds <= 0)
                {
                    inst.Stop();
                    mapContainer.isPaused = true;
                    MessageBoxScreen gameOverMessageBoxScreen = new MessageBoxScreen("The Dungeon Falled Apart.. YOU DIED\n" + mapContainer.PrintFinalResult(true), false);
                    gameOverMessageBoxScreen.Accepted += clearMessageBox_Accepted;
                    ScreenManager.AddScreen(gameOverMessageBoxScreen);
                }
                else if (mapContainer.PlayerHP <= 0)
                {
                    inst.Stop();
                    mapContainer.isPaused = true;
                    string[] ang = { "Ouch! That hurt a lot...", "Burnt to ashes.." };
                    MessageBoxScreen gameOverMessageBoxScreen = new MessageBoxScreen(ang[ScreenManager.r.Next(ang.Length)] + "\n" +
                        mapContainer.PrintFinalResult(true) + "\nTime Left = " + timeLeft.Minutes + ":" + timeLeft.Seconds + ":" + timeLeft.Milliseconds / 10
                        , false);
                    gameOverMessageBoxScreen.Accepted += clearMessageBox_Accepted;
                    ScreenManager.AddScreen(gameOverMessageBoxScreen);
                }
            }

            mapViewOrigin = mapContainer.PlayerPosition;

            base.Update(gameTime, otherScreenHasFocus, false);
        }
        protected void readyMessageBox_Accepted(object sender, EventArgs e)
        {
            mapContainer.isPaused = false;
        }
        protected void clearMessageBox_Accepted(object sender, EventArgs e)
        {
            ScreenManager.AddScreen(new MainMenuScreen());
            LoadingScreen.Load(ScreenManager, false, new MainMenuScreen());
        }
        protected void escapeMessageBox_Accepted(object sender, EventArgs e)
        {
            mapContainer.isPaused = true;
            string[] ang = { "You escaped and LIVED", "The ignorant protagonist runs away." };
            MessageBoxScreen gameOverMessageBoxScreen = new MessageBoxScreen(ang[ScreenManager.r.Next(ang.Length)] + "\n" +
                mapContainer.PrintFinalResult(false) + "\nTime Left = " + timeLeft.Minutes + ":" + timeLeft.Seconds + ":" + timeLeft.Milliseconds / 10
                , false);
            gameOverMessageBoxScreen.Accepted += clearMessageBox_Accepted;
            ScreenManager.AddScreen(gameOverMessageBoxScreen);
        }
        protected void escapeMessageBox_Cancelled(object sender, EventArgs e)
        {
            mapContainer.isPaused = false;
        }

        public override void Draw(GameTime gameTime)
        {
            // map
            ScreenManager.GraphicsDevice.Viewport = mapViewport;
            mapContainer.Draw(gameTime, ScreenManager.SpriteBatch, mapViewOrigin);

            // status bar
            ScreenManager.GraphicsDevice.Viewport = statusBarViewport;
            ScreenManager.SpriteBatch.Begin();
            ScreenManager.SpriteBatch.Draw(ScreenManager.HeartTexture, new Rectangle(35, 20, 32, 32), Color.AliceBlue);
            ScreenManager.SpriteBatch.DrawString(ScreenManager.SmallFont, " x " + mapContainer.PlayerHP, new Vector2(80, 32), mapContainer.PlayerHP == 1 ? Color.Red : Color.White);
            ScreenManager.SpriteBatch.DrawString(ScreenManager.SmallFont, "Time : " + timeLeft.Minutes +":"+ timeLeft.Seconds +":"+ timeLeft.Milliseconds / 10, new Vector2(35, 80), timeLeft.Minutes >= 1 ? Color.White : Color.Red);
            ScreenManager.SpriteBatch.DrawString(ScreenManager.SmallFont, "Score : " + mapContainer.PlayerScore, new Vector2(35, 120), mapContainer.PlayerScore > 10000 ? Color.Red : mapContainer.PlayerScore > 5000 ? Color.Green : Color.White);
            if (mapContainer.PlayerCapacity > 1) 
                ScreenManager.SpriteBatch.DrawString(ScreenManager.SmallFont, "Capacity : " + mapContainer.PlayerCapacity, new Vector2(35, 160), Color.White);
            mapContainer.DrawRescued(ScreenManager.SpriteBatch);
            //ScreenManager.SpriteBatch.DrawString(ScreenManager.SmallFont, "X : " + mapContainer.PlayerPosition.X + "\nY : " + mapContainer.PlayerPosition.Y, new Vector2(35, 160), Color.Blue);
            //ScreenManager.SpriteBatch.DrawString(ScreenManager.SmallFont, "Tile X : " + mapContainer.TilePosition.X + "\nTile Y : " + mapContainer.TilePosition.Y, new Vector2(35, 240), Color.Blue);
            //ScreenManager.SpriteBatch.DrawString(ScreenManager.SmallFont, "Room X : " + mapContainer.RoomPosition.X + "\nRoom Y : " + mapContainer.RoomPosition.Y, new Vector2(35, 320), Color.Blue);
            float baseDirection = -(float)Math.Atan2((mapContainer.RoomPosition.X - 4) * mapContainer.mapWidth + mapContainer.TilePosition.X - 5, (mapContainer.RoomPosition.Y - 4) * mapContainer.mapHeight + mapContainer.TilePosition.Y - 5);
            ScreenManager.SpriteBatch.Draw(ScreenManager.CompassTexture, new Rectangle(100, 450, 128, 128), null, Color.White, baseDirection, new Vector2(64f, 64f), SpriteEffects.None, 0f);
            ScreenManager.SpriteBatch.End();

            ScreenManager.GraphicsDevice.Viewport = defaultViewport;

            // If the game is transitioning on or off, fade it out to black.
            if (TransitionPosition > 0 || pauseAlpha > 0)
            {
                float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);

                ScreenManager.FadeBackBufferToBlack(alpha);
            }
        }

    }

}
